package com.gzone.contentprovider.sql.service;

import java.util.ArrayList;
import java.util.Date;

import android.content.Context;
import android.util.Log;

import com.gzone.contentprovider.helper.DataHelper;
import com.gzone.contentprovider.sql.dao.CategoryDAO;
import com.gzone.contentprovider.sql.dao.HitDAO;
import com.gzone.contentprovider.sql.dao.ItemDAO;
import com.gzone.contentprovider.sql.dao.SelectionDAO;
import com.gzone.contentprovider.sql.model.Category;
import com.gzone.contentprovider.sql.model.Hit;
import com.gzone.contentprovider.sql.model.Item;
import com.gzone.contentprovider.sql.model.Persistent;
import com.gzone.contentprovider.sql.model.Selection;
import com.gzone.contentprovider.utils.DateTimeUtil;

public class DatabaseServices {
	private static final String DATE_TIME_FORMAT = "yyyy-MM-DD HH:MM:SS.SSS";
	private CategoryDAO categoryDAO;
	private HitDAO hitDAO;
	private ItemDAO itemDAO;
	private SelectionDAO selectionDAO;

	private static DatabaseServices ds;
	public static DatabaseServices getInstance(Context context) {
		if (ds == null) {
			ds = new DatabaseServices(context);
		}
		return ds;
	}

	private DatabaseServices(Context context){
		DataHelper.initialize(context);
		categoryDAO = new CategoryDAO();
		hitDAO = new HitDAO();
		itemDAO = new ItemDAO();
		selectionDAO = new SelectionDAO();
		
//		insertDBTest();
	}
	
	
	
	public void insertDBTest() {
		for(int i =0; i < 5; i++){
			Category cat = new Category();
			cat.id = i + 1;
			cat.app_name = "cat_" + i + "_item";
			cat.bgURL = "images/desserts1.jpg";
			cat.imgURL = "images/desserts1.jpg";
			cat.desc = "images/desserts1.jpg";
			cat.order = i;
			cat.syncdate = DateTimeUtil.dateToString(new Date(System.currentTimeMillis()), DATE_TIME_FORMAT);
			cat.title="Category " + i;
			Item item = new Item();
			item.category_id = i + 1;
			item.id = i + 1;
			item.desc = "Item " + i;
			item.iconURL = "images/cheese_280x180.jpg";
			item.imgURL = "images/cheese_280x180.jpg";
			item.like = i;
			item.order = i + 1;
			item.price = "1000";
			item.syncdate = DateTimeUtil.dateToString(new Date(System.currentTimeMillis()), DATE_TIME_FORMAT);
			item.title = " Item " + i;
			
			insert(cat);
			cat.destroy();
			insert(item);
			item.destroy();
		}
	}



	public void synchronizeDB(String dataItem, String dataCategory){
		ArrayList<Item> listItemFromServer = itemDAO.readJSONData(dataItem);
		ArrayList<Category> listCategoryFromServer = categoryDAO.readJSONData(dataCategory);
//		synchronizeDB(listItemFromServer,listCategoryFromServer);
	}
	
	public void synchronizeCategory(String data){
		ArrayList<Category> listCategoryFromServer = categoryDAO.readJSONData(data);
		ArrayList<Category> listCategoryClient = categoryDAO.findAllToUpdate();
		int length = 0;
		Category temp = null;
		boolean isExited = false;
		Log.i("Synchronize", "--->Server " + listCategoryFromServer.size());
		for(int i = 0; i < listCategoryFromServer.size(); i++){
			isExited = false;
			temp = listCategoryFromServer.get(i);
			length = listCategoryClient.size();
			Log.i("Synchronize", "--->Client " + length);
			for(int j = 0; j < length; j++){
				if(temp.id == listCategoryClient.get(j).id){
					isExited = true;
					if(!temp.syncdate.equals(listCategoryClient.get(j).syncdate)){
						categoryDAO.update(temp);
					}
					listCategoryClient.remove(j);
					length = listCategoryClient.size();
//					temp = null;
//					listCategoryFromServer.remove(i);
				}
			}
			if(!isExited){
				categoryDAO.insert(temp);
//				temp = null;
//				listCategoryFromServer.remove(i);
			}
		}
		//delete old category
		for(int i = 0; i < listCategoryClient.size(); i++){
			categoryDAO.delete(listCategoryClient.get(i));
		}
	}
	public void synchronizeItem(String dataItem){
		ArrayList<Item> listItemFromServer = itemDAO.readJSONData(dataItem);
//		for(Item item : listItemFromServer){
//			Log.i("Synchronize", "---> " + item.iconURL);
//		}
		//step 5
		//Update Item
		//check update item
		int length = 0;
		boolean isExited = false;
		ArrayList<Item> listItemClient = itemDAO.findAllToUpdate();
		for(int i = 0; i < listItemFromServer.size(); i++){
			Item temp = listItemFromServer.get(i);
			length = listItemClient.size();
//			Log.i("Synchronize", "--->Server " + listItemFromServer.size());
//			Log.i("Synchronize", "--->Client " + length);
			isExited = false;
			for(int j = 0; j < length; j++){
				if(temp.id == listItemClient.get(j).id){
					Log.i("Synchronize", "--->update " + temp.price + "--" + (temp.id == listItemClient.get(j).id));
					isExited = true;
					if(!temp.syncdate.equals(listItemClient.get(j).syncdate)){
						itemDAO.update(temp);
						Log.i("Synchronize", "--->update " + length);
					}
					listItemClient.remove(j);
					length = listItemClient.size();
//					Log.i("Synchronize", "--->update " + length);
//					temp = null;
//					listItemFromServer.remove(i);
				}
			}
			
			if(!isExited){
				itemDAO.insert(temp);
				Log.i("Synchronize", "--->Insert " + temp.id);
//				temp = null;
//				listItemFromServer.remove(i);
			}
		}
		//delete old item
		for(Item item : listItemClient){
			itemDAO.delete(item);
			Log.i("Synchronize", "--->Delete " + item.category_id);
		}
	}
	private void synchronizeDB(ArrayList<Item> listItemFromServer, ArrayList<Category> listCategoryFromServer){
		//Step 3
		hitDAO.deleteAllRow();
		//Step 4
		//Update Category
		//check for update
		ArrayList<Category> listCategoryClient = categoryDAO.findAllToUpdate();
		int length = 0;
		boolean isExited = false;
		for(int i = 0; i < listCategoryFromServer.size(); i++){
			isExited = false;
			Category temp = listCategoryFromServer.get(i);
			length = listCategoryClient.size();
			for(int j = 0; j < length; i++){
				if(temp.id == listCategoryClient.get(j).id){
					isExited = true;
					if(!temp.syncdate.equals(listCategoryClient.get(j).syncdate)){
						categoryDAO.update(temp);
					}
					listCategoryClient.remove(j);
					length = listCategoryClient.size();
					temp = null;
					listCategoryFromServer.remove(i);
				}
				if(!isExited){
					categoryDAO.insert(temp);
					temp = null;
					listCategoryFromServer.remove(i);
				}
			}
		}
		//delete old category
		for(int i = 0; i < listCategoryClient.size(); i++){
			categoryDAO.delete(listCategoryClient.get(i));
		}
		//step 5
		//Update Item
		//check update item
		ArrayList<Item> listItemClient = itemDAO.findAllToUpdate();
		for(int i = 0; i < listItemFromServer.size(); i++){
			Item temp = listItemFromServer.get(i);
			length = listItemClient.size();
			isExited = false;
			for(int j = 0; j < length; j++){
				if(temp.id == listItemClient.get(j).id){
					isExited = true;
					if(temp.syncdate.equals(listItemClient.get(j).syncdate)) itemDAO.update(temp);
					listItemClient.remove(j);
					temp = null;
					listItemFromServer.remove(i);
				}
			}
			
			if(!isExited){
				itemDAO.insert(temp);
				temp = null;
				listItemFromServer.remove(i);
			}
		}
		//delete old item
		for(Item item : listItemClient){
			itemDAO.delete(item);
		}
		
		//Step 6
		selectionDAO.deleteAllRow();
	}
	
	public void update(Persistent object){
		if(object instanceof Item){
			itemDAO.update((Item)object);
		}else if(object instanceof Category){
			categoryDAO.update((Category)object);
		}else if(object instanceof Selection){
			selectionDAO.update((Selection)object);
		}else if(object instanceof Hit){
			hitDAO.update((Hit)object);
		}
	}
	public void insert(Persistent object){
		if(object instanceof Item){
			itemDAO.insert((Item)object);
		}else if(object instanceof Category){
			categoryDAO.insert((Category)object);
		}else if(object instanceof Selection){
			selectionDAO.insert((Selection)object);
		}else if(object instanceof Hit){
			hitDAO.insert((Hit)object);
		}
	}
	
	public ArrayList<Item> getAllItem(){
		return itemDAO.findAll();
	}
	
	public void destroy(){
		DataHelper.close();
		ds = null;
	}

	public ArrayList<Category> getAllCategory() {
		return categoryDAO.findAll();
	}
	
	public CategoryDAO getCategoryDAO(){
		return categoryDAO;
	}
	
	public ItemDAO getItemDAO(){
		return itemDAO;
	}
	
	public HitDAO getHitDAO(){
		return hitDAO;
	}
	
	public SelectionDAO getSelectionDAO(){
		return selectionDAO;
	}
}
